#pragma once

#include <functional>
#include <uv.h>
#include <session.h>
#include <string>

using Socket = std::shared_ptr<uv_tcp_t>;
using accept_handle = std::function<void(Socket)>;
using connect_handle = std::function<void()>;


class Dispatcher {
	public:
		Dispatcher(Session*);
		void Create_Socket();
		void Connect(std::string ip, int port, connect_handle handle);
		void Bind(std::string ip, int port);
		void Listen(accept_handle handle, int n=1024);
		std::shared_ptr<uv_tcp_t> GetTcpHandle();
		static void Loop();
		void Stop();
		~Dispatcher();

	private:
		friend void on_connect(uv_connect_t* conn, int status);
		friend void on_client_connect(uv_stream_t* s, int status);
	private:
		static uv_loop_t* mLoop;
		std::shared_ptr<uv_tcp_t> mSocket;
		uv_connect_t* mConn;
		sockaddr_in mDest;
		Session* mSession;
		static accept_handle mAcceptHandler;
		static connect_handle mConnectHandler;
};
